package com.googlecode.player.controller.mediators
{
	import com.googlecode.data.materials.VideoStreamMaterialVO;
	import com.googlecode.data.objects3d.MaterialsListObject3DVO;
	import com.googlecode.data.objects3d.SingleMaterialObject3DVO;
	import com.googlecode.player.model.Animator3DPlayerProxy;
	import com.googlecode.player.view.specialmaterials.ControlledVideoStreamMaterial;
	
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	
	import org.papervision3d.materials.VideoStreamMaterial;
	import org.puremvc.as3.multicore.interfaces.IProxy;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class VideoStreamMediator extends Mediator
	{
		/**
		 * Name prefix used to create dynamic mediator names.
		 * Names will be appended by the INSTANCE_COUNT to create a unique mediator name. 
		 */
		public static const NAME_PREFIX:String = "VideoStreamMediator";
		
		/**
		 * Counter indicating how many instances of this class have been created. 
		 */		
		protected static var INSTANCE_COUNT:uint = 0;
		
		/**
		 * Reference to the object3D. 
		 */
		private var _object3D:*;
		
		/**
		 * Constructor 
		 * @param object3D
		 * 
		 */
		public function VideoStreamMediator(object3D:*)
		{
			super(NAME_PREFIX + INSTANCE_COUNT);
			
			_object3D = object3D;

			// update instance count so we obtain a unique name for each Mediator instance
			INSTANCE_COUNT++;
		}
		
		/**
		 * Called by PureMVC framework. 
		 * 
		 */
		override public function onRegister():void
		{	
			var mat:VideoStreamMaterialVO;
			
			if(_object3D is SingleMaterialObject3DVO)
			{
				mat = (_object3D as SingleMaterialObject3DVO).material as VideoStreamMaterialVO;
			}
			
			if(_object3D is MaterialsListObject3DVO)
			{
				mat = (_object3D as MaterialsListObject3DVO).materialsList[(_object3D as MaterialsListObject3DVO).selectedFace];
			}
			
			var vidMat:*;
			
			if(mat.showControls)
			{
				vidMat = new ControlledVideoStreamMaterial((mat as VideoStreamMaterialVO).filePath);
			}else
			{
				// now set up the video stream
				var customClient:Object = new Object();
						
				/* MetaDataHandler is a function that catches the metaData
				if you don't have this flash will throw an error */
				customClient.onMetaData = metaDataHandler; 
				
				var connection:NetConnection = new NetConnection();
				connection.connect(null);
				
				var netStream:NetStream = new NetStream(connection);
				netStream.client = customClient;
				netStream.play((mat as VideoStreamMaterialVO).filePath);
				
				var video:Video = new Video();
				video.smoothing = true;
				video.attachNetStream(netStream);
				
				vidMat = new VideoStreamMaterial(video, netStream);
			}
			

			if(_object3D is SingleMaterialObject3DVO)
			{

				settings.scene.getChildByName((_object3D as SingleMaterialObject3DVO).name).material = vidMat;
			}
			
			if(_object3D is MaterialsListObject3DVO)
			{
				settings.scene.getChildByName((_object3D as MaterialsListObject3DVO).name).replaceMaterialByName(vidMat, (_object3D as MaterialsListObject3DVO).selectedFace);
			}
			
		}
		
		/**
		 * Called as part of the video streaming process.  
		 * @param infoObject
		 * 
		 */
		protected function metaDataHandler(infoObject:Object):void 
		{
			//
		}
		
		/**
		 * Returns typed reference to model. 
		 * @return 
		 * 
		 */
		protected function get settings():Animator3DPlayerProxy
		{
			var proxy:IProxy = facade.retrieveProxy(Animator3DPlayerProxy.NAME);
			
			return proxy as Animator3DPlayerProxy;
		}
	}
}